<?php
/**
 * Handles repository links parsing.
 * @copyright (c) 2012, University of Amsterdam
 * @author Athanasios Papapanagiotou <hello@thanpa.com>
 * @author Huy Hoang <hhoang.nl@gmail.com>
 * @author Khoi Anh	Ho <khoi.ho@tomtom.com>
 * @author Tuba Kaya Chomette <admin@tubakaya.com>
 */
class RepositoryLinks
{
    /**
     * Holds the keywords to link with.
     * @var array
     */
    private $_keywords;
    /**
     * Sets the keywords to use.
     * @param array $keywords
     * @return \Repository_Links
     */
    public function setKeywords(array $keywords) {
        $this->_keywords = $keywords;
        return $this;
    }
    /**
     * Parses the file and saves the results in the db.
     * @param string $logfile The file to parse.
     */
    public function parse($logfile)
    {
        $handle = fopen($logfile, "r");
        if (!$handle) {
            throw new Exception("Log file '{$logfile}' is not readable.");
        }
        $dao = new DAO_Links();
        $commit = array();
        while (!feof($handle)) {
            $buffer = fgets($handle, 4096);
            if ((bool)preg_match('/commit ([a-zA-Z]|\d+)/', $buffer)) {
                if (!empty($commit)) {
                    $links = $this->_parseCommit($commit);
                    if (!empty($links)) {
                        $dao->save($links);
                    }
                }
                $commit = array();
            }
            $commit[] = $buffer;
        }
        fclose($handle);
    }
    /**
     * Parses a single commit and returns any links found.
     * @param array $commit The commit splited in lines.
     * @return array The links found in the commit.
     */
    private function _parseCommit($commit)
    {
        if (!isset($commit[4]) || !isset($commit[1])) {
            return array();
        }
        $keywords = $this->_getKeywords($commit[4]);
        $links = array();
        foreach ($keywords as $keyword) {
            $links[] = array(
                'Objects' => array(
                    'Author' => $this->_getAuthor($commit[1]),
                    'Keyword' => $keyword,
                ),
                'Action' => 'commit',
            );
        }
        return $links;
    }
    /**
     * Returns the keywords that exist in the string provided.
     * @param string $str The string to search.
     * @return array The keywords found.
     */
    private function _getKeywords($str)
    {
        $str = strtolower($str);
        $keywords = $this->_keywords;
        foreach ($keywords as $key => $keyword) {
            $keyword = strtolower($keyword);
            if (!(bool)preg_match("/{$keyword}/", $str)) {
                unset($keywords[$key]);
            }
        }
        sort($keywords);
        return $keywords;
    }
    /**
     * Returns the name of the author of the commit.
     * @param strint $str The line to parse.
     * @return string The name of the author.
     */
    private function _getAuthor($str)
    {
        $start = strpos($str, ':') + 2;
        $length = strpos($str, '<') - $start - 1;
        return substr($str, $start, $length);
    }
}